#! /usr/bin/env python3
# -*- coding: utf-8 -*-

#第二部分 数据结构 
#第二章 序列构成的数组

enWords = "abc"
#列表推导式
unicodes = [ord(x) for x in enWords]
print(unicodes)

#列表推导式与if
nums = [10,20,30,40,50,60]
bigNums = [x for x in nums if x>=50 ] #注意 if语句的位置
print(bigNums)

#笛卡尔积
#通过列表推导式 嵌套循环得到笛卡尔积
tshirts = [ (color,size) for color in ['red','green','blue'] for size in ['38','39','40','41']]
print(tshirts)

#生成器表达式
tshirts = ( (color,size) for color in ['red','green','blue'] for size in ['38','39','40','41'])
print(tshirts) #这是一个生成器 ，生成器不会马上生成元素 而是在执行循环或者next函数的时候才生成元素
print(next(tshirts)) 

def fn(a,b,c):
    print(a,b,c)

tpl = (1,2,3,4,6)
#fn(*tpl) #拆包元组作为函数参数,元素长度必须和函数参数个数相同

a,b,*res = tpl #拆包赋值 *res 形式可以把剩余的放进一个list里面
print(a,b,res,type(res))
*ret,a,b = tpl #带星的可以放在任意位置
print(a,b,ret,type(ret))

#命名元组或者说具名元素(创建一个简单的类)
from collections import namedtuple

City = namedtuple("City","name country populations") #第一个参数表示元素名称 第二个参数表示元组个字段名(空格隔开的字符串或者一个字符串组成的迭代对象)

c = City(name='湛江',country="中国",populations='500万')
print(c.name)   
print(City._fields) #获取所有字段

#切片
ary = [1,2,3,4,5,6,7,8,9]

ary[2:5] = [20,30]
print(ary)
del ary[3:5]
print(ary)

#列表的+和*运算

ary = ['a','b','c']

ary *= 3 #得到三个原ary拼接的列表
ary.extend(['d','e']) #合并
id(ary) #地址值
print(ary) 

t = (1,2,[20,30])
# t[2] += [40,50] #这步操作会抛出异常，因为tuple是不可以变的 不能进行自增操作
print(t)

#排序函数list.sort和sorted

ary = [(color,size) for color in ['red','green','blue'] for size in ['38','39','40','41']]

ary.sort(key=lambda x:x[1]) #根据尺寸排序 改变原始list sorted则不改变原列表返回新列表
#print(ary)

#bisect模块,可以在一个序列中插入一个元素 但是序列依然是有序的
import bisect

ary = [10,20,30,50,70,80]
idx = bisect.bisect(ary,40) #返回的索引 表示在此索引之前的元素都比40小
print(idx)
ary.insert(idx,40) #插入元素到相应位置 list依然是有序的

bisect.insort(ary,40) #一步完成插入而不改变序列的顺序

print('bisect_left=',bisect.bisect_left(ary,30),'bisect_right=',bisect.bisect_right(ary,30))

#bisect.bisect_left 返回相等元素的位置 bisect_right返回相等元素+1的位置

#array.array 数组
import sys,os
from array import array
from random import random

print(os.path.split(__file__),os.path.sep)

#把数组内容写入文件 和读取文件内容到数组
size = 5
floats1 = array('d',[random() for i in range(0,size)])

url = os.path.split(__file__)[0]
url = os.path.join(url,'floats.bin')
with open(url,'wb') as f:
    floats1.tofile(f) #写入二进制文件

floats2 = array('d')
with open(url,'rb') as f:
    floats2.fromfile(f,size) #读取二进制到array
print(floats2[0])

# memoryview 是一个内置类，它能让用户在不复制内容的情况下操作同一个数组的不同切片

menv = memoryview(floats2)
print(menv,menv[0])
menv = menv[1:3]
print(menv.tolist(),floats2)

from collections import deque #双向队列
from queue import Queue #队列

dq = deque([1,2,3,4,5,6,7,8,9])
dq.rotate(3) #把右边的三个元素移动到左边 传负数则相反
print(dq) # 7, 8, 9, 1, 2, 3, 4, 5, 6 












